#- Use module for Vala
# Provides functions to compile Vala and Genie sources. It is assumed that
# FindVala.cmake has already been loaded. Refer to FindVala.cmake for
# information on how to use Vala in your CMake project.

#=============================================================================
# Copyright 2009-2010 Michael Wild, Kitware Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
#  License text for the above reference.)

# Modified by Jukka-Pekka Partanen (jukpart@gmail.com) to find out C compiler
# include dirs, library dirs and libraries for vala packages (gtk+-3.0 etc.)
# See ../COPYING-CMAKE-SCRIPTS for copying


include(ParseArguments)
macro(ensure_vala_version version)
    parse_arguments(ARGS "" "MINIMUM;MAXIMUM;EXACT" ${ARGN})
	set(compare_message "")
	set(error_message "")
	if(ARGS_MINIMUM)
		set(compare_message "a minimum ")
		set(error_message "or greater ")
	elseif(ARGS_MAXIMUM)
		set(compare_message "a maximum ")
		set(error_message "or less ")
	endif(ARGS_MINIMUM)

	message(STATUS
		"checking for ${compare_message}Vala version of ${version}"
	)

	unset(version_accepted)

	# MINIMUM is the default if no option is specified
	if(ARGS_EXACT)
		if(${VALA_VERSION} VERSION_EQUAL ${version} )
			set(version_accepted TRUE)
		endif(${VALA_VERSION} VERSION_EQUAL ${version})
	elseif(ARGS_MAXIMUM)
		if(${VALA_VERSION} VERSION_LESS ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
			set(version_accepted TRUE)
		endif(${VALA_VERSION} VERSION_LESS ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
	else(ARGS_MAXIMUM)
		if(${VALA_VERSION} VERSION_GREATER ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
			set(version_accepted TRUE)
		endif(${VALA_VERSION} VERSION_GREATER ${version} OR ${VALA_VERSION} VERSION_EQUAL ${version})
	endif(ARGS_EXACT)

	if (NOT version_accepted)
		message(FATAL_ERROR
			"Vala version ${version} ${error_message}is required."
		)
	endif(NOT version_accepted)
endmacro(ensure_vala_version)

# target properties
define_property(TARGET PROPERTY PUBLIC_VAPI_FILE
  BRIEF_DOCS ".vapi file generated by either GENERATE_VAPI or LIBRARY option."
  FULL_DOCS "If a Vala target is created with GENERATE_VAPI or the LIBRARY "
  "option, the location of the generated public .vapi file is stored in this "
  "property.")

define_property(TARGET PROPERTY INTERNAL_VAPI_FILE
  BRIEF_DOCS ".vapi file generated by the GENERATE_INTERNAL_VAPI option."
  FULL_DOCS "If a Vala target is created with GENERATE_INTERNAL_VAPI option, "
  "the location of the generated internal .vapi file is stored in this "
  "property.")

define_property(TARGET PROPERTY VAPI_FILES
  BRIEF_DOCS ".vapi files required to link against this library."
  FULL_DOCS "Names the .vapi file describing the C GLib/GObject interface "
  "defined by a Vala library in the Vala language such that it can be used "
  "by other Vala code and all other .vapi files this library depends on.")

define_property(TARGET PROPERTY VALA_PACKAGE_DEPENDENCIES
  BRIEF_DOCS "Dependencies from Vala targets used with PACKAGES"
  FULL_DOCS "Target names of Vala libraries that have been passed using the "
  "PACKAGES option of vala_precompile, vala_add_executable or "
  "vala_add_library on which this target depends. This property is "
  "inherited by other targets that list this target in their "
  "PACKAGES option.")

define_property(TARGET PROPERTY VALA_C_SOURCES
  BRIEF_DOCS "The generated C-sources"
  FULL_DOCS "The functions vala_add_executable and vala_add_library store in "
  "this property the paths of the generated C-sources as returned by "
  "vala_precompile.")

# include directories
include_directories(${VALA_INCLUDE_DIRS})

# compiler flags
set(VALA_COMPILE_FLAGS "" CACHE STRING "Flags used by the Vala compiler")
set(VALA_COMPILE_FLAGS_DEBUG "-g" CACHE STRING
  "Flags used by the Vala compiler during debug builds")
set(VALA_COMPILE_FLAGS_MINSIZEREL "" CACHE STRING
  "Flags used by the Vala compiler during release minsize builds")
set(VALA_COMPILE_FLAGS_RELEASE "" CACHE STRING
  "Flags used by the Vala compiler during release builds")
set(VALA_COMPILE_FLAGS_RELWITHDEBINFO "-g" CACHE STRING
  "Flags used by the Vala compiler during release with Debug Info builds")
mark_as_advanced(VALA_COMPILE_FLAGS VALA_COMPILE_FLAGS_DEBUG
  VALA_COMPILE_FLAGS_MINSIZEREL VALA_COMPILE_FLAGS_RELEASE
  VALA_COMPILE_FLAGS_RELWITHDEBINFO)

function(vala_precompile target outvar)
  set(in_files)
  set(out_files)
  set(result)
  set(vala_pkg_opts)
  set(depends)
  set(depends_vapis)
  set(vapi_arguments)
  set(header_arguments)
  set(valid_args
    PACKAGES LIBRARY COMPILE_FLAGS VAPI_DIRS GENERATE_HEADER
    GENERATE_INTERNAL_HEADER GENERATE_VAPI GENERATE_INTERNAL_VAPI CUSTOM_VAPIS
    BASE_DIR OUTPUT_DIR COMMENT LINK_PATH LINK_WITH
    )
  _vala_parse_arguments(ARGS "${valid_args}" "" ${ARGN})

   # deal with PACKAGES
   foreach(pkg ${ARGS_PACKAGES})
     # if it is a target, the user wants us to do things automagically
     if(TARGET "${pkg}")
       # add the target and its own dependencies to the list depends
       list(APPEND depends ${pkg})
       get_target_property(pkg_depends ${pkg} VALA_PACKAGE_DEPENDENCIES)
       if(pkg_depends)
         list(APPEND depends ${pkg_depends})
       endif()
     else()
       # otherwise just put --pkg
       list(APPEND vala_pkg_opts "--pkg=${pkg}")
     endif()
   endforeach()
   # get the vapis of the dependencies
   foreach(d ${depends})
     get_target_property(vapi_file ${d} VAPI_FILES)
     if(vapi_file)
       list(APPEND depends_vapis "${vapi_file}")
     endif()
   endforeach()

   # deal with OUTPUT_DIR (make it absolute if its not) and ensure it exists
   if(NOT ARGS_OUTPUT_DIR)
     set(${ARGS_OUTPUT_DIR} "${CMAKE_CURRENT_BINARY_DIR}")
   endif()
   if(NOT IS_ABSOLUTE "${ARGS_OUTPUT_DIR}")
     set(ARGS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARGS_OUTPUT_DIR}")
   endif()
   if(NOT IS_DIRECTORY "${ARGS_OUTPUT_DIR}")
     file(MAKE_DIRECTORY "${ARGS_OUTPUT_DIR}")
   endif()

   # deal with LIBRARY. if GENERATE_VAPI is not specified, add it here
   if(ARGS_LIBRARY)
     list(APPEND VALA_COMPILE_FLAGS "--library=${ARGS_LIBRARY}")
     if(NOT ARGS_GENERATE_VAPI)
       set(ARGS_GENERATE_VAPI "${ARGS_LIBRARY}.vapi")
     endif()
   endif()

   # deal with CUSTOM_VAPIS. ensure every vapi shows up only once
   set(vapi_files ${ARGS_CUSTOM_VAPIS} ${depends_vapis})
   if(vapi_files)
     list(REMOVE_DUPLICATES vapi_files)
   endif()

   # deal with COMPILE_FLAGS
   if(ARGS_COMPILE_FLAGS)
     list(APPEND VALA_COMPILE_FLAGS "${ARGS_COMPILE_FLAGS}")
   endif()

   # deal with VAPI_DIRS
   if(ARGS_VAPI_DIRS)
     set(VALA_VAPI_DIRS "${ARGS_VAPI_DIRS}")
   endif()
   set(vala_vapidir_opts)
   foreach(vapidir ${VALA_VAPI_DIRS})
     list(APPEND vala_vapidir_opts "--vapidir=${vapidir}")
   endforeach()

   # deal with BASE_DIR and make it absolute
   if(NOT ARGS_BASE_DIR)
     set(ARGS_BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
   endif()
   if(NOT IS_ABSOLUTE "${ARGS_BASE_DIR}")
     set(ARGS_BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_BASE_DIR}")
   endif()

   # treat source files
   foreach(src ${ARGS_DEFAULT_ARGS})
     if(NOT IS_ABSOLUTE "${src}")
       get_filename_component(src "${src}" ABSOLUTE)
     endif()
     list(APPEND in_files "${src}")
     file(RELATIVE_PATH out_file "${ARGS_BASE_DIR}" "${src}")
     string(REGEX REPLACE "\\.(vala|gs)$" ".c" out_file
       "${ARGS_OUTPUT_DIR}/${CMAKE_CFG_INTDIR}/${out_file}")
     # remove back-references
     get_filename_component(out_file "${out_file}" ABSOLUTE)
     list(APPEND out_files "${out_file}")
     list(APPEND result "${out_file}")
   endforeach()

   # deal with GENERATE_INTERNAL_VAPI (make absolute if necessary and create
   # destination directory)
   if(ARGS_GENERATE_INTERNAL_VAPI)
     # Header and internal header is needed to generate internal vapi
     if (NOT ARGS_GENERATE_HEADER)
       set(ARGS_GENERATE_HEADER ${ARGS_GENERATE_VAPI})
     endif()
     if (NOT ARGS_GENERATE_INTERNAL_HEADER)
       set(ARGS_GENERATE_INTERNAL_HEADER ${ARGS_GENERATE_HEADER}_internal)
     endif()
     if(NOT IS_ABSOLUTE "${ARGS_GENERATE_INTERNAL_VAPI}")
       set(ARGS_GENERATE_INTERNAL_VAPI
         "${ARGS_OUTPUT_DIR}/${ARGS_GENERATE_INTERNAL_VAPI}")
     endif()
     get_filename_component(_genvapidir "${ARGS_GENERATE_INTERNAL_VAPI}" PATH)
     list(APPEND out_files "${ARGS_GENERATE_INTERNAL_VAPI}")
     set(vapi_arguments "--internal-vapi=${ARGS_GENERATE_INTERNAL_VAPI}")
   endif()

   # the same for GENERATE_VAPI
   if(ARGS_GENERATE_VAPI)
     if(NOT IS_ABSOLUTE "${ARGS_GENERATE_VAPI}")
       set(ARGS_GENERATE_VAPI "${ARGS_OUTPUT_DIR}/${ARGS_GENERATE_VAPI}")
     endif()
     list(APPEND out_files "${ARGS_GENERATE_VAPI}")
     set(vapi_arguments "--vapi=${ARGS_GENERATE_VAPI}")
   endif()

   # deal with GENERATE_HEADER, making absolute and creating output dir
   if(ARGS_GENERATE_HEADER)
     if(NOT IS_ABSOLUTE "${ARGS_GENERATE_HEADER}")
       set(ARGS_GENERATE_HEADER "${ARGS_OUTPUT_DIR}/${ARGS_GENERATE_HEADER}")
     endif()
     list(APPEND out_files "${ARGS_GENERATE_HEADER}")
     list(APPEND header_arguments "--header=${ARGS_GENERATE_HEADER}")
     list(APPEND result "${ARGS_GENERATE_HEADER}")
   endif()

   # the same for GENERATE_INTERNAL_HEADER
   if(ARGS_GENERATE_INTERNAL_HEADER)
     if(NOT IS_ABSOLUTE "${ARGS_GENERATE_INTERNAL_HEADER}")
       set(ARGS_GENERATE_INTERNAL_HEADER
         "${ARGS_OUTPUT_DIR}/${CMAKE_CFG_INTDIR}/${ARGS_GENERATE_INTERNAL_HEADER}")
     endif()
     list(APPEND out_files "${ARGS_GENERATE_INTERNAL_HEADER}")
     list(APPEND header_arguments
       "--internal-header=${ARGS_GENERATE_INTERNAL_HEADER}")
     list(APPEND result "${ARGS_GENERATE_INTERNAL_HEADER}")
   endif()

   # allow override of COMMENT
   if(NOT ARGS_COMMENT)
     set(ARGS_COMMENT "Precompiling Vala target ${target}")
   endif()

   # create a .cmake file to drive the precompiling
   # (sadly, this is required for multi-configuration IDE's to support
   # VALA_COMPILE_FLAGS_<BUILD_TYPE> flags)
   set(driver_file
     "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${target}.dir/precompile.cmake")
   if(CMAKE_CONFIGURATION_TYPES)
     set(config_types ${CMAKE_CONFIGURATION_TYPES})
   else()
     set(config_types Debug Release RelWithDebInfo MinSizeRel ${CMAKE_BUILD_TYPE})
     list(REMOVE_DUPLICATES config_types)
   endif()
   set(vala_config_flags)
   foreach(c IN LISTS config_types)
     string(TOUPPER ${c} cc)
     set(v VALA_COMPILE_FLAGS_${cc})
     set(vala_config_flags "${vala_config_flags}set(${v} \"${${v}}\")\n")
   endforeach()

   set(command
     "\${VALA_COMPILER}" -C
     ${header_arguments}
     ${vapi_arguments}
     -b "${ARGS_BASE_DIR}"
     -d "${ARGS_OUTPUT_DIR}/\${CMAKE_CFG_INTDIR}"
     ${vala_vapidir_opts}
     ${vala_pkg_opts}
     @VALA_COMPILE_FLAGS@
     ${in_files}
     ${vapi_files}
     )
   configure_file("${VALA_CMAKE_DIR}/ValaDriver.cmake.in"
     "${driver_file}" @ONLY)

   # create the actual command to precompile (don't list out_files in the OUTPUT
   # but use a stamp file instead, because valac only updates changed files)
   set(stamp_file
     "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${target}.dir/precompile.stamp")
   if(NOT CMAKE_CFG_INTDIR STREQUAL .)
     set(stamp_file "${stamp_file}.${CMAKE_CFG_INTDIR}")
   endif()
   if(CMAKE_GENERATOR MATCHES "Makefiles$")
     set(verbose "$(VERBOSE)")
   else()
     set(verbose 1)
   endif()
   add_custom_command(OUTPUT ${stamp_file}
     COMMAND "${CMAKE_COMMAND}"
       -DVALA_COMPILER:FILEPATH=${VALA_COMPILER}
       -DCMAKE_CFG_INTDIR:STRING=${CMAKE_CFG_INTDIR}
       -DVERBOSE:STRING=${verbose}
       -P "${driver_file}"
     COMMAND "${CMAKE_COMMAND}" -E touch "${stamp_file}"
     DEPENDS "${VALA_COMPILER}" ${in_files} ${ARGS_CUSTOM_VAPIS} "${driver_file}"
     WORKING_DIRECTORY "${ARGS_OUTPUT_DIR}"
     COMMENT "${ARGS_COMMENT}"
     VERBATIM
     )

   # mark the products as GENERATED and for automatic cleaning
   set_source_files_properties(${out_files} PROPERTIES GENERATED TRUE)
   set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
     ADDITIONAL_MAKE_CLEAN_FILES ${out_files})

   # add custom target to depend on
   add_custom_target(${target} DEPENDS ${stamp_file})
   # have it depend on the targets in PACKAGES and their dependencies
   if(depends)
     add_dependencies(${target} ${depends})
   endif()
   # set our own dependencies property
   set_property(TARGET ${target} APPEND PROPERTY
     VALA_PACKAGE_DEPENDENCIES ${depends})
   # add the internal vapi to the list of vapis this library requires (if it is one)
   if(ARGS_GENERATE_INTERNAL_VAPI)
     list(APPEND vapi_files "${ARGS_GENERATE_INTERNAL_VAPI}")
   elseif(ARGS_GENERATE_VAPI)
     # otherwise use the public vapi
     list(APPEND vapi_files "${ARGS_GENERATE_VAPI}")
   endif()
   # set the properties describing this Vala target
   set_target_properties(${target} PROPERTIES
     VAPI_FILES "${vapi_files}"
     PUBLIC_VAPI_FILE "${ARGS_GENERATE_VAPI}"
     INTERNAL_VAPI_FILE "${ARGS_GENERATE_INTERNAL_VAPI}"
     )
   # propagate generated sources and headers to caller scope
   set(${outvar} "${result}" PARENT_SCOPE)
 endfunction()

 function(vala_add_executable name)
   set(valid_args PACKAGES VAPI_DIRS CUSTOM_VAPIS BASE_DIR COMPILE_FLAGS
     OUTPUT_DIR COMMENT LINK_PATH LINK_WITH)
   _vala_parse_arguments(ARGS "${valid_args}" "" ${ARGN})
   # repack the arguments
   set(ARGS)
   foreach(v ${valid_args})
     if(ARGS_${v})
       list(APPEND ARGS ${v} "${ARGS_${v}}")
     endif()
   endforeach()
   # precompile
   vala_precompile(${name}_precompile C_SOURCES
     ${ARGS_DEFAULT_ARGS} ${ARGS})
   # add the executable target
   add_executable(${name} ${C_SOURCES})
   # declare the dependency and inherit the custom properties
   vala_add_dependencies(${name} ${name}_precompile)
   set(_link_flags)
   if(ARGS_LINK_PATH)
     foreach(p ${ARGS_LINK_PATH})
        set(_link_flags "${_link_flags} -L${p}")
     endforeach()
   endif()
   if(ARGS_VAPI_DIRS)
     foreach(p ${ARGS_VAPI_DIRS})
       set(_compile_flags "${_compile_flags} -I${p}")
     endforeach()
   endif()

   set(PACKAGES_LIBRARIES)
   find_package(PkgConfig REQUIRED)
   set(i "1")
   foreach(p ${ARGS_PACKAGES})
       message (STATUS "Check for package ${p} -->")
       pkg_check_modules(PKG${i} REQUIRED ${p})
       string(REPLACE ";" " -I" tmp "${PKG${i}_INCLUDE_DIRS}")
       set(_compile_flags "${_compile_flags} -I${tmp}")
       if(PKG${i}_LIBRARY_DIRS)
          string(REPLACE ";" " -L" tmp "${PKG${i}_LIBRARY_DIRS}")
          set(_link_flags "${_link_flags} -L${tmp}")
       endif()
       set(PACKAGES_LIBRARIES "${PACKAGES_LIBRARIES};${PKG${i}_LIBRARIES}")
       message (STATUS "${p} INCLUDE_DIRS: ${PKG${i}_INCLUDE_DIRS}")
       message (STATUS "${p} LIBRARY_DIRS: ${PKG${i}_LIBRARY_DIRS}")
       message (STATUS "${p} LIBRARIES: ${PKG${i}_LIBRARIES}")
       set(i "${i}1")
   endforeach()

  # set the VALA_C_SOURCES property
  set_target_properties(${name} PROPERTIES
    VALA_C_SOURCES "${C_SOURCES}"
    COMPILE_FLAGS "${_compile_flags}"
    LINK_FLAGS "${_link_flags}"
  )
  # link against VALA_LIBRARIES
  target_link_libraries(${name} ${VALA_LIBRARIES} ${ARGS_LINK_WITH} ${PACKAGES_LIBRARIES})
endfunction()

function(vala_add_library name type)
  set(valid_args LIBRARY PACKAGES VAPI_DIRS CUSTOM_VAPIS GENERATE_VAPI
    GENERATE_HEADER GENERATE_INTERNAL_HEADER BASE_DIR COMPILE_FLAGS OUTPUT_DIR
    COMMENT LINK_PATH LINK_WITH)
  _vala_parse_arguments(ARGS "${valid_args}" "" ${ARGN})
  # repack the arguments
  set(ARGS)
  foreach(v ${valid_args})
    if(ARGS_${v})
      list(APPEND ARGS ${v} "${ARGS_${v}}")
    endif()
  endforeach()
  # deal with type being a source file
  if(NOT type MATCHES "^(STATIC|SHARED|MODULE)")
    list(INSERT ARGS_DEFAULT_ARGS 0 "${type}")
    set(type)
  endif()
  # deal with LIBRARY
  set(library_args)
  if(NOT ARGS_LIBRARY)
    set(library_args LIBRARY ${name})
  endif()
  # precompile
  vala_precompile(${name}_precompile C_SOURCES
    ${ARGS_DEFAULT_ARGS}
    ${library_args} ${ARGS})
  # add the library target
  add_library(${name} ${type} ${C_SOURCES})
  # declare dependency and inherit custom properties
  vala_add_dependencies(${name} ${name}_precompile)
  set(_link_flags)
  if(ARGS_LINK_PATH)
    foreach(p ${ARGS_LINK_PATH})
       set(_link_flags "${_link_flags} -L${p}")
    endforeach()
  endif()
  if(ARGS_VAPI_DIRS)
    foreach(p ${ARGS_VAPI_DIRS})
      set(_compile_flags "${_compile_flags} -I${p}")
    endforeach()
  endif()

   set(PACKAGES_LIBRARIES)
   find_package(PkgConfig REQUIRED)
   set(i "1")
   foreach(p ${ARGS_PACKAGES})
       message (STATUS "Check for package ${p} -->")
       pkg_check_modules(PKG${i} REQUIRED ${p})
       string(REPLACE ";" " -I" tmp "${PKG${i}_INCLUDE_DIRS}")
       set(_compile_flags "${_compile_flags} -I${tmp}")
       if(PKG${i}_LIBRARY_DIRS)
          string(REPLACE ";" " -L" tmp "${PKG${i}_LIBRARY_DIRS}")
          set(_link_flags "${_link_flags} -L${tmp}")
       endif()
       set(PACKAGES_LIBRARIES "${PACKAGES_LIBRARIES};${PKG${i}_LIBRARIES}")
       message (STATUS "${p} INCLUDE_DIRS: ${PKG${i}_INCLUDE_DIRS}")
       message (STATUS "${p} LIBRARY_DIRS: ${PKG${i}_LIBRARY_DIRS}")
       message (STATUS "${p} LIBRARIES: ${PKG${i}_LIBRARIES}")
       set(i "${i}1")
   endforeach()

  # inherit library specific properties
  get_target_property(vapi ${name} PUBLIC_VAPI)
  get_target_property(ivapi ${name} INTERNAL_VAPI)
  set_target_properties(${name} PROPERTIES
    VALA_C_SOURCES "${C_SOURCES}"
    PUBLIC_VAPI "${vapi}"
    INTERNAL_VAPI "${ivapi}"
    COMPILE_FLAGS "${_compile_flags}"
    LINK_FLAGS "${_link_flags}"
    )
  # link against VALA_LIBRARIES
  target_link_libraries(${name} ${VALA_LIBRARIES} ${ARGS_LINK_WITH} ${PACKAGES_LIBRARIES})
endfunction()

function(vala_add_dependencies target)
  # inherit custom properties
  set(vapi_files)
  set(pkg_deps)
  foreach(dep ${ARGN})
    if(TARGET ${dep})
      get_property(is_vala_target TARGET ${dep} PROPERTY VAPI_FILES SET)
      if(is_vala_target)
        get_target_property(v ${dep} VAPI_FILES)
        get_target_property(p ${dep} VALA_PACKAGE_DEPENDENCIES)
        list(APPEND vapi_files ${v})
        list(APPEND pkd_deps ${p})
      endif()
    else()
      message(SEND_ERROR "Dependency ${dep} is not a top-level target")
    endif()
  endforeach()
  set_property(TARGET ${target} APPEND PROPERTY VAPI_FILES ${vapi_files})
  set_property(TARGET ${target} APPEND PROPERTY
    VALA_PACKAGE_DEPENDENCIES ${pkg_deps})
  add_dependencies(${target} ${ARGN})
endfunction()

##
# This is a helper Macro to parse optional arguments in Macros/Functions. It
# has been taken from the public CMake wiki. See
# http://www.cmake.org/Wiki/CMakeMacroParseArguments for documentation and
# licensing.
##
function(_vala_parse_arguments prefix arg_names option_names)
  # initialize
  set(DEFAULT_ARGS)
  foreach(arg_name ${arg_names})
    set(result_${arg_name})
  endforeach()
  foreach(option ${option_names})
    set(result_${option} FALSE)
  endforeach()
  # parse
  set(current_arg_name DEFAULT_ARGS)
  set(current_arg_list)
  foreach(arg ${ARGN})
    set(larg_names ${arg_names})
    list(FIND larg_names "${arg}" is_arg_name)
    if(is_arg_name GREATER -1)
      set(result_${current_arg_name} ${current_arg_list})
      set(current_arg_name ${arg})
      set(current_arg_list)
    else(is_arg_name GREATER -1)
      set(loption_names ${option_names})
      list(FIND loption_names "${arg}" is_option)
      if(is_option GREATER -1)
            set(result_${arg} TRUE)
      else(is_option GREATER -1)
            set(current_arg_list ${current_arg_list} ${arg})
      endif()
    endif()
  endforeach()
  set(result_${current_arg_name} ${current_arg_list})
  # propagate to caller scope
  foreach(arg_name DEFAULT_ARGS ${arg_names})
    set(${prefix}_${arg_name} ${result_${arg_name}} PARENT_SCOPE)
  endforeach()
  foreach(option ${option_names})
    set(${prefix}_${option} ${result_${option}} PARENT_SCOPE)
  endforeach()
endfunction()
